package com.iakuil.app.mpg;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.generator.FastAutoGenerator;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
import com.baomidou.mybatisplus.generator.config.OutputFile;
import com.baomidou.mybatisplus.generator.config.rules.DateType;
import com.iakuil.app.common.core.BaseController;
import com.iakuil.app.common.core.BaseService;
import com.iakuil.app.common.core.DefaultConverterConfig;
import com.iakuil.app.common.core.constant.SysConstant;
import com.iakuil.app.common.core.domain.BaseEntity;
import com.iakuil.app.common.core.domain.BaseQuery;
import com.iakuil.app.common.core.domain.Result;
import com.iakuil.app.common.core.util.MapUtils;
import com.iakuil.app.repository.base.CrudMapper;
import com.iakuil.app.service.base.BaseServiceImpl;

import java.util.HashMap;
import java.util.Map;

/**
 * 加强版MPG代码生成器
 *
 * <p>同时生成Entity和各种DTO
 *
 * @author Kai
 * @date 2021/12/17 12:45
 **/
public class CodeGen {

    private static final DataSourceConfig.Builder DATA_SOURCE_CONFIG = new DataSourceConfig
        .Builder(GenConstant.DB_URL, GenConstant.DB_USERNAME, GenConstant.DB_PASSWD);

    public static void main(String... args) {
        Map<OutputFile, String> pathInfo = new HashMap<>();
        pathInfo.put(OutputFile.entity, GenConstant.ENTITY_OUTPUT_DIR);
        pathInfo.put(OutputFile.mapper, GenConstant.MAPPER_OUTPUT_DIR);
        pathInfo.put(OutputFile.xml, GenConstant.XML_OUTPUT_DIR);
        pathInfo.put(OutputFile.service, GenConstant.SERVICE_OUTPUT_DIR);
        pathInfo.put(OutputFile.serviceImpl, GenConstant.SERV_IMPL_OUTPUT_DIR);
        pathInfo.put(OutputFile.controller, GenConstant.CONTR_OUTPUT_DIR);

        FastAutoGenerator.create(DATA_SOURCE_CONFIG)
            .templateEngine(new CustomTemplateEngine())
            // 全局配置
            .globalConfig((scanner, builder) -> builder.author(GenConstant.AUTHOR)
                .enableSwagger() // 开启 swagger 模式
                .outputDir(GenConstant.ROOT_DIR) // 指定输出目录
                .dateType(DateType.ONLY_DATE) // 时间策略
                .disableOpenDir()
            )

            // 包配置
            .packageConfig((scanner, builder) -> builder.parent(SysConstant.CORP_DOMAIN_NAME)
                .moduleName(SysConstant.APP_SYMBOL) // 设置父包模块名
                .entity("domain.entity")
                .service("service")
                .serviceImpl("service.impl")
                .mapper("repository.dao")
                .controller("api.controller")
                .pathInfo(pathInfo)
            )

            // 策略配置
            .strategyConfig(builder -> builder.addInclude(GenConstant.TABLE_INCLUDES)
                .addTablePrefix("sys_", "t_") // 设置过滤表前缀
                .entityBuilder()
                .superClass(BaseEntity.class)
                .disableSerialVersionUID()
                .enableLombok()
                .enableRemoveIsPrefix()
                .versionColumnName("version")
                .versionPropertyName("version")
                .logicDeleteColumnName("deleted")
                .logicDeletePropertyName("deleted")
                .addSuperEntityColumns("create_by", "create_time", "update_by", "update_time")
                .idType(IdType.ASSIGN_ID)

                .controllerBuilder()
                .superClass(BaseController.class)
                // .enableHyphenStyle()
                .enableRestStyle()

                .serviceBuilder()
                .superServiceClass(BaseService.class)
                .formatServiceFileName("%sService")
                .superServiceImplClass(BaseServiceImpl.class)

                .mapperBuilder()
                .superClass(CrudMapper.class)
                .enableBaseResultMap()
                .enableBaseColumnList()
                .formatXmlFileName("%sMapper")
            )

            // 模板配置
            .templateConfig(builder -> builder.entity("templates/entity.java")
                .controller("templates/controller.java"))

            // 注入配置
            .injectionConfig(builder -> builder.customMap(MapUtils.<String, Object>builder()
                .put("package_BaseQuery", BaseQuery.class.getName())
                .put("package_resp", Result.class.getName())
                .put("package_converter_config", DefaultConverterConfig.class.getName())
                .put("package_dto", GenConstant.DTO_PACKAGE)
                .put(GenConstant.DTO_OUTPUT_KEY, GenConstant.DTO_OUTPUT_DIR)
                .build()
            ))

            // 执行代码生成
            .execute();
    }
}
